import { 
  TagService as ITagService,
  Tag, 
  DocumentTag,
  SearchServiceResult,
  SEARCH_STORAGE_KEYS,
  TAG_COLORS,
  SEARCH_LIMITS
} from './types';
import { simpleStorageAdapter } from '../export/simpleStorageAdapter';

export class TagService implements ITagService {
  private tagsCache: Tag[] = [];
  private documentTagsCache: Map<string, string[]> = new Map(); // documentId -> tagIds
  private tagDocumentsCache: Map<string, string[]> = new Map(); // tagId -> documentIds

  /**
   * 创建标签
   */
  async createTag(name: string, color: string, description?: string): Promise<Tag> {
    try {
      // 验证输入
      const validationError = this.validateTagInput(name, color, description);
      if (validationError) {
        throw new Error(validationError);
      }

      // 检查是否已存在同名标签
      const existingTags = await this.getAllTags();
      const existingTag = existingTags.find(tag => tag.name.toLowerCase() === name.toLowerCase());
      if (existingTag) {
        throw new Error(`标签 "${name}" 已存在`);
      }

      const newTag: Tag = {
        id: this.generateId(),
        name: name.trim(),
        color,
        description: description?.trim(),
        usageCount: 0,
        createdAt: Date.now(),
        updatedAt: Date.now()
      };

      // 添加到缓存
      this.tagsCache.push(newTag);
      
      // 保存到存储
      await this.saveTags();
      
      console.log('[TagService] 标签创建成功:', newTag.name);
      return newTag;

    } catch (error) {
      console.error('[TagService] 创建标签失败:', error);
      throw error;
    }
  }

  /**
   * 更新标签
   */
  async updateTag(tagId: string, updates: Partial<Tag>): Promise<void> {
    try {
      const tags = await this.getAllTags();
      const tagIndex = tags.findIndex(tag => tag.id === tagId);
      
      if (tagIndex === -1) {
        throw new Error(`标签不存在: ${tagId}`);
      }

      // 验证更新数据
      if (updates.name !== undefined) {
        const validationError = this.validateTagInput(updates.name, updates.color || tags[tagIndex].color, updates.description);
        if (validationError) {
          throw new Error(validationError);
        }

        // 检查名称冲突
        const nameConflict = tags.find(tag => 
          tag.id !== tagId && tag.name.toLowerCase() === updates.name!.toLowerCase()
        );
        if (nameConflict) {
          throw new Error(`标签 "${updates.name}" 已存在`);
        }
      }

      // 更新标签
      const updatedTag = {
        ...tags[tagIndex],
        ...updates,
        updatedAt: Date.now()
      };

      // 保护某些字段不被直接更新
      updatedTag.id = tags[tagIndex].id;
      updatedTag.createdAt = tags[tagIndex].createdAt;
      updatedTag.usageCount = tags[tagIndex].usageCount; // 使用量由系统维护

      // 更新缓存
      this.tagsCache[tagIndex] = updatedTag;
      
      // 保存到存储
      await this.saveTags();
      
      console.log('[TagService] 标签更新成功:', updatedTag.name);

    } catch (error) {
      console.error('[TagService] 更新标签失败:', error);
      throw error;
    }
  }

  /**
   * 删除标签
   */
  async deleteTag(tagId: string): Promise<void> {
    try {
      const tags = await this.getAllTags();
      const tagIndex = tags.findIndex(tag => tag.id === tagId);
      
      if (tagIndex === -1) {
        throw new Error(`标签不存在: ${tagId}`);
      }

      const tag = tags[tagIndex];

      // 删除所有文档的该标签关联
      const documentTags = await this.loadDocumentTags();
      const updatedDocumentTags = documentTags.filter(dt => dt.tagId !== tagId);
      
      // 更新缓存
      this.tagsCache.splice(tagIndex, 1);
      this.updateDocumentTagsCache(updatedDocumentTags);
      
      // 保存到存储
      await this.saveTags();
      await this.saveDocumentTags(updatedDocumentTags);
      
      console.log('[TagService] 标签删除成功:', tag.name);

    } catch (error) {
      console.error('[TagService] 删除标签失败:', error);
      throw error;
    }
  }

  /**
   * 获取标签
   */
  async getTag(tagId: string): Promise<Tag | null> {
    try {
      const tags = await this.getAllTags();
      return tags.find(tag => tag.id === tagId) || null;
    } catch (error) {
      console.error('[TagService] 获取标签失败:', error);
      return null;
    }
  }

  /**
   * 获取所有标签
   */
  async getAllTags(): Promise<Tag[]> {
    try {
      if (this.tagsCache.length > 0) {
        return this.tagsCache;
      }

      const result = await simpleStorageAdapter.get<Tag[]>(SEARCH_STORAGE_KEYS.TAGS);
      if (result.success && result.data) {
        this.tagsCache = result.data.sort((a, b) => b.usageCount - a.usageCount);
      }
      
      return this.tagsCache;
    } catch (error) {
      console.error('[TagService] 获取标签列表失败:', error);
      return [];
    }
  }

  /**
   * 为文档添加标签
   */
  async addTagToDocument(documentId: string, tagId: string): Promise<void> {
    try {
      // 验证标签是否存在
      const tag = await this.getTag(tagId);
      if (!tag) {
        throw new Error(`标签不存在: ${tagId}`);
      }

      // 检查是否已关联
      const documentTags = await this.getDocumentTags(documentId);
      if (documentTags.some(t => t.id === tagId)) {
        console.log('[TagService] 文档已关联该标签:', documentId, tagId);
        return;
      }

      // 检查标签数量限制
      if (documentTags.length >= SEARCH_LIMITS.MAX_TAGS_PER_DOCUMENT) {
        throw new Error(`每个文档最多只能添加${SEARCH_LIMITS.MAX_TAGS_PER_DOCUMENT}个标签`);
      }

      // 添加关联
      const documentTagRelations = await this.loadDocumentTags();
      documentTagRelations.push({
        documentId,
        tagId,
        addedAt: Date.now()
      });

      // 更新标签使用次数
      await this.incrementTagUsage(tagId);

      // 更新缓存
      this.updateDocumentTagsCache(documentTagRelations);
      
      // 保存到存储
      await this.saveDocumentTags(documentTagRelations);
      
      console.log('[TagService] 文档标签关联成功:', documentId, '->', tagId);

    } catch (error) {
      console.error('[TagService] 添加文档标签失败:', error);
      throw error;
    }
  }

  /**
   * 从文档移除标签
   */
  async removeTagFromDocument(documentId: string, tagId: string): Promise<void> {
    try {
      const documentTagRelations = await this.loadDocumentTags();
      const relationIndex = documentTagRelations.findIndex(dt => 
        dt.documentId === documentId && dt.tagId === tagId
      );

      if (relationIndex === -1) {
        console.log('[TagService] 文档标签关联不存在:', documentId, tagId);
        return;
      }

      // 删除关联
      documentTagRelations.splice(relationIndex, 1);

      // 减少标签使用次数
      await this.decrementTagUsage(tagId);

      // 更新缓存
      this.updateDocumentTagsCache(documentTagRelations);
      
      // 保存到存储
      await this.saveDocumentTags(documentTagRelations);
      
      console.log('[TagService] 文档标签移除成功:', documentId, '-x->', tagId);

    } catch (error) {
      console.error('[TagService] 移除文档标签失败:', error);
      throw error;
    }
  }

  /**
   * 获取文档的所有标签
   */
  async getDocumentTags(documentId: string): Promise<Tag[]> {
    try {
      const tagIds = this.documentTagsCache.get(documentId) || await this.loadDocumentTagIds(documentId);
      const allTags = await this.getAllTags();
      
      return tagIds
        .map(tagId => allTags.find(tag => tag.id === tagId))
        .filter((tag): tag is Tag => tag !== undefined);
        
    } catch (error) {
      console.error('[TagService] 获取文档标签失败:', error);
      return [];
    }
  }

  /**
   * 获取使用某标签的所有文档ID
   */
  async getTagDocuments(tagId: string): Promise<string[]> {
    try {
      return this.tagDocumentsCache.get(tagId) || await this.loadTagDocumentIds(tagId);
    } catch (error) {
      console.error('[TagService] 获取标签文档失败:', error);
      return [];
    }
  }

  /**
   * 获取标签使用统计
   */
  async getTagUsageStats(): Promise<{tagId: string; count: number}[]> {
    try {
      const tags = await this.getAllTags();
      return tags
        .map(tag => ({ tagId: tag.id, count: tag.usageCount }))
        .sort((a, b) => b.count - a.count);
    } catch (error) {
      console.error('[TagService] 获取标签统计失败:', error);
      return [];
    }
  }

  /**
   * 智能标签建议
   */
  async suggestTags(content: string): Promise<string[]> {
    try {
      const suggestions: string[] = [];
      const contentLower = content.toLowerCase();
      const tags = await this.getAllTags();

      // 基于标签名称匹配内容
      for (const tag of tags) {
        if (contentLower.includes(tag.name.toLowerCase())) {
          suggestions.push(tag.name);
        }
      }

      // 基于简单关键词映射（可扩展）
      const keywordMappings = [
        { keywords: ['新闻', '报道', '采访'], tag: '新闻' },
        { keywords: ['技术', '开发', '编程'], tag: '技术' },
        { keywords: ['分析', '报告', '总结'], tag: '分析' },
        { keywords: ['会议', '纪要', '讨论'], tag: '会议' },
        { keywords: ['计划', '方案', '策略'], tag: '规划' }
      ];

      for (const mapping of keywordMappings) {
        if (mapping.keywords.some(keyword => contentLower.includes(keyword))) {
          if (!suggestions.includes(mapping.tag)) {
            suggestions.push(mapping.tag);
          }
        }
      }

      return suggestions.slice(0, 5); // 最多返回5个建议
    } catch (error) {
      console.error('[TagService] 生成标签建议失败:', error);
      return [];
    }
  }

  /**
   * 获取热门标签
   */
  async getPopularTags(limit: number = 10): Promise<Tag[]> {
    try {
      const tags = await this.getAllTags();
      return tags
        .filter(tag => tag.usageCount > 0)
        .slice(0, limit);
    } catch (error) {
      console.error('[TagService] 获取热门标签失败:', error);
      return [];
    }
  }

  // 私有方法

  /**
   * 验证标签输入
   */
  private validateTagInput(name: string, color: string, description?: string): string | null {
    if (!name || !name.trim()) {
      return '标签名称不能为空';
    }

    if (name.trim().length > SEARCH_LIMITS.MAX_TAG_NAME_LENGTH) {
      return `标签名称不能超过${SEARCH_LIMITS.MAX_TAG_NAME_LENGTH}个字符`;
    }

    if (!color) {
      return '标签颜色不能为空';
    }

    if (description && description.length > SEARCH_LIMITS.MAX_TAG_DESCRIPTION_LENGTH) {
      return `标签描述不能超过${SEARCH_LIMITS.MAX_TAG_DESCRIPTION_LENGTH}个字符`;
    }

    return null;
  }

  /**
   * 加载文档标签关联数据
   */
  private async loadDocumentTags(): Promise<DocumentTag[]> {
    try {
      const result = await simpleStorageAdapter.get<DocumentTag[]>(SEARCH_STORAGE_KEYS.DOCUMENT_TAGS);
      return result.success && result.data ? result.data : [];
    } catch (error) {
      console.error('[TagService] 加载文档标签关联失败:', error);
      return [];
    }
  }

  /**
   * 加载特定文档的标签ID列表
   */
  private async loadDocumentTagIds(documentId: string): Promise<string[]> {
    const documentTags = await this.loadDocumentTags();
    const tagIds = documentTags
      .filter(dt => dt.documentId === documentId)
      .map(dt => dt.tagId);
    
    this.documentTagsCache.set(documentId, tagIds);
    return tagIds;
  }

  /**
   * 加载特定标签的文档ID列表
   */
  private async loadTagDocumentIds(tagId: string): Promise<string[]> {
    const documentTags = await this.loadDocumentTags();
    const documentIds = documentTags
      .filter(dt => dt.tagId === tagId)
      .map(dt => dt.documentId);
    
    this.tagDocumentsCache.set(tagId, documentIds);
    return documentIds;
  }

  /**
   * 更新文档标签缓存
   */
  private updateDocumentTagsCache(documentTags: DocumentTag[]): void {
    this.documentTagsCache.clear();
    this.tagDocumentsCache.clear();

    for (const dt of documentTags) {
      // 更新文档 -> 标签映射
      const docTags = this.documentTagsCache.get(dt.documentId) || [];
      if (!docTags.includes(dt.tagId)) {
        docTags.push(dt.tagId);
        this.documentTagsCache.set(dt.documentId, docTags);
      }

      // 更新标签 -> 文档映射
      const tagDocs = this.tagDocumentsCache.get(dt.tagId) || [];
      if (!tagDocs.includes(dt.documentId)) {
        tagDocs.push(dt.documentId);
        this.tagDocumentsCache.set(dt.tagId, tagDocs);
      }
    }
  }

  /**
   * 增加标签使用次数
   */
  private async incrementTagUsage(tagId: string): Promise<void> {
    const tags = await this.getAllTags();
    const tagIndex = tags.findIndex(tag => tag.id === tagId);
    
    if (tagIndex >= 0) {
      this.tagsCache[tagIndex].usageCount++;
      this.tagsCache[tagIndex].updatedAt = Date.now();
      await this.saveTags();
    }
  }

  /**
   * 减少标签使用次数
   */
  private async decrementTagUsage(tagId: string): Promise<void> {
    const tags = await this.getAllTags();
    const tagIndex = tags.findIndex(tag => tag.id === tagId);
    
    if (tagIndex >= 0 && this.tagsCache[tagIndex].usageCount > 0) {
      this.tagsCache[tagIndex].usageCount--;
      this.tagsCache[tagIndex].updatedAt = Date.now();
      await this.saveTags();
    }
  }

  /**
   * 保存标签到存储
   */
  private async saveTags(): Promise<void> {
    try {
      await simpleStorageAdapter.set(SEARCH_STORAGE_KEYS.TAGS, this.tagsCache);
    } catch (error) {
      console.error('[TagService] 保存标签失败:', error);
      throw error;
    }
  }

  /**
   * 保存文档标签关联到存储
   */
  private async saveDocumentTags(documentTags: DocumentTag[]): Promise<void> {
    try {
      await simpleStorageAdapter.set(SEARCH_STORAGE_KEYS.DOCUMENT_TAGS, documentTags);
    } catch (error) {
      console.error('[TagService] 保存文档标签关联失败:', error);
      throw error;
    }
  }

  /**
   * 生成唯一ID
   */
  private generateId(): string {
    return `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  /**
   * 获取随机标签颜色
   */
  static getRandomColor(): string {
    return TAG_COLORS[Math.floor(Math.random() * TAG_COLORS.length)];
  }
}

// 导出服务单例
let tagServiceInstance: TagService | null = null;

export function createTagService(): TagService {
  if (!tagServiceInstance) {
    tagServiceInstance = new TagService();
  }
  return tagServiceInstance;
}

export const tagService = createTagService();